import {reactive, isReactive, isRef} from "vue";
import {waitTimeout} from "@/utils/tools.js";

const usePaging = (options) => {
    // 返回的分页对象
    const paging = reactive({
        loading: false,
        pageNum: 1,
        pageSize: 10,
        total: 0,
        list: [],
        load: null
    })
    // 保存参数，用来判断接口返回数据是否接收
    var oldParams = '';

    // 加载数据，type true:重新加载，false:加载更多，reload更新当前页码的数据
    paging.load = async (type) => {
        // 参数
        let opt = typeof options == 'function' ? options() : options;
        // 如果传入的参数不是方法，不是响应式数据，则报错
        if(typeof options !== 'function') {
            if(opt.params && typeof opt.params !== 'function' && (!isRef(opt.params) && !isReactive(opt.params))) {
                console.error('params参数必须是响应式对象或者函数');
                return;
            }
        }
        if(!opt.api) {
            console.error('api接口方法不能为空');
            return;
        }

        opt = Object.assign({
            pageNumKey: 'pageNum',
            pageSizeKey: 'pageSize',
            params: null, // 可以是响应式对象，可以是函数
            api: null, // promise对象
            format: null, // 数据格式化函数
            callback: null, // 回调函数
        }, opt);
        if(opt.pageSize) {
            paging.pageSize = opt.pageSize;
        }

        let pageNum = paging.pageNum, pageSize = paging.pageSize;
        if(type === true) {
            pageNum = 1;
        } else if(type === 'reload') {
            pageSize = pageNum*pageSize;
            pageNum = 1;
        } else {
            pageNum++;
        }
        
        // 传入的参数为函数时，执行函数，返回参数
        let inPrm = typeof opt.params === 'function' ? opt.params() : (opt.params || {});
        let params = {};
        if(typeof inPrm === 'string') {
            params = inPrm+`&${opt.pageNumKey}=${pageNum}&${opt.pageSizeKey}=${pageSize}`;
        } else {
            params = {...inPrm};
            params[opt.pageNumKey] = pageNum;
            params[opt.pageSizeKey] = pageSize;
        }
        
        paging.loading = true;
        try {
            oldParams = params;
            let res = await opt.api(params);
            // await waitTimeout(1000);
            if(!checkParams(oldParams, params)) {
                console.log('参数不一致不接收数据', oldParams, params);
                return;
            }

            // 格式化数据
            let data = res.data || [];
            data = opt.format ? opt.format(data) : data;

            // 保存数据到list
            if(type === 'reload') {
                paging.list = data;
            } else {
                if(type === true) {
                    paging.list = data;
                } else {
                    paging.list = [...paging.list, ...data];
                }
                paging.pageNum = pageNum;
            }

            // 保存总数
            paging.total = res.total || 0;

            // 执行回调
            opt.callback && opt.callback(paging.list);
        } finally {
            if(paging.total == -1) {
                paging.total = 0;
            }
            paging.loading = false;
        }
    }

    // 验证参数是否一致
    function checkParams(oldVal, newVal) {
        if(typeof oldVal != typeof newVal) {
            return false;
        }
        if(typeof oldVal == 'object') {
            return JSON.stringify(oldVal) == JSON.stringify(newVal);
        }
        return oldVal == newVal;
    }

    return paging;
}

export default usePaging;